<template>
  <div class="swiper">
    <div class="swiper__inner" @touchstart="start" @touchmove="move" @touchend="end">
      <transition :name="slideName">
        <div class="swiper__item" @click="swiperClick" v-if="current === show" key="swiperItem1st">
          <img :class="['swiper__image', mode]" :src="content[show]" v-if="type === 'image'">
          <span class="swiper__text" v-else-if="type === 'text'">{{content[show]}}</span>
        </div>
        <div class="swiper__item" @click="swiperClick" v-if="current === hide" key="swiperItem2nd">
          <img :class="['swiper__image', mode]" :src="content[hide]" v-if="type === 'image'">
          <span class="swiper__text" v-else-if="type === 'text'">{{content[hide]}}</span>
        </div>
      </transition>
    </div>
  </div>
</template>

<script>
export default {
  name: 'swiper',
  props: {
    // 当前活跃索引，默认为 0（第一项）
    active: {
      type: Number,
      default: 0
    },
    // 是否自动播放，默认为 true
    autoplay: {
      type: Boolean,
      default: false
    },
    // 轮播内容数组
    content: {
      type: Array,
      default: function () {
        return []
      }
    },
    // 延迟时间（秒），默认为 3秒
    duration: {
      type: Number,
      default: 3
    },
    /**
     * scaleToFill: 不保持纵横比缩放图片，使图片的宽高完全拉伸至填满 image 元素
     * aspectFit: 保持纵横比缩放图片，使图片的长边能完全显示出来。也就是说，可以完整地将图片显示出来
     */
    mode: {
      type: String,
      default: 'scaleToFill'
    },
    // 轮播内容类型，默认为 图片
    type: {
      type: String,
      default: 'image'
    }
  },
  data () {
    return {
      current: 0,
      show: 0,
      hide: 1,
      interval: 0,
      slideName: 'slide-left',
      tsx: 0,
      tex: 0
    }
  },
  methods: {
    swiperSlide () {
      window.clearInterval(this.interval)
      this.interval = window.setInterval(() => {
        this.slideName = 'slide-left'

        let len = this.content.length
        this.current = (this.current === len - 1 ? 0 : ++this.current)

        if (this.current !== this.show) {
          this.show += 2
          this.show -= (this.show >= len ? len : 0)
        }
        if (this.current !== this.hide) {
          this.hide += 2
          this.hide -= (this.hide >= len ? len : 0)
        }
      }, this.duration * 1000)
    },

    swiperClick () {
      this.$emit('handleSwiperClick', this.current)
    },

    start (e) {
      window.clearInterval(this.interval)
      let touches = e.targetTouches
      this.tsx = touches[touches.length - 1].pageX
    },

    move (e) {
      // 修正 ios 下左右滑动导致页面上下滚动的体验问题
      e.preventDefault()
      e.stopPropagation()
    },

    end (e) {
      e.stopPropagation()
      let touches = e.changedTouches
      this.tex = touches[touches.length - 1].pageX

      if (this.tex - this.tsx > 100) {
        this.slideName = 'slide-right'

        let len = this.content.length
        this.current = this.current === 0 ? len - 1 : --this.current

        if (this.current !== this.show) {
          this.show -= 2
          this.show += (this.show < 0 ? len : 0)
        }
        if (this.current !== this.hide) {
          this.hide -= 2
          this.hide += (this.hide < 0 ? len : 0)
        }
      } else if (this.tex - this.tsx < -100) {
        this.slideName = 'slide-left'

        let len = this.content.length
        this.current = this.current === len - 1 ? 0 : ++this.current

        if (this.current !== this.show) {
          this.show += 2
          this.show -= (this.show >= len ? len : 0)
        }
        if (this.current !== this.hide) {
          this.hide += 2
          this.hide -= (this.hide >= len ? len : 0)
        }
      }

      this.autoplay && this.swiperSlide()
    }
  },
  created () {
    this.current = this.active
    this.show = this.active
    this.hide = this.active + 1
    if (this.content.length > 1 && this.hide === this.content.length) {
      this.hide = 0
    }

    this.autoplay && this.swiperSlide()
  },
  watch: {
    current () {
      this.$emit('getSwiperActive', this.current)
    }
  }
}
</script>

<style scoped lang="scss">
.swiper {
  height: 100%;
  position: relative;
  width: 100%;
  z-index: 5;
  overflow: hidden;
  &__inner {
    height: 100%;
    overflow: hidden;
    position: relative;
    width: 100%;
  }

  &__item {
    align-items: center;
    display: flex;
    height: 100%;
    justify-content: center;
    width: 100%;
  }

  &__image {
    &.aspectFit {
      max-height: 100%;
      max-width: 100%;
    }

    &.scaleToFill {
      height: 100%;
      width: 100%;
    }
  }

  &__text {
    text-align: left;
    width: 100%;
  }
}
</style>
